package com.easy.frame.base.basic.util;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.Format;
import java.util.*;

/**
 * ObjectUtil
 *
 * @author Achin
 * @create 2019-01-14 16:11
 */
public class ObjectUtils {

    /**
     * 判断字符串是否为空
     */
    public static boolean isNull(String str) {
        return null == str || "".equals(str);
    }

    /**
     * 判断对象是否为空
     */
    public static boolean isNull(Object o) {
        return null == o;
    }

    /**
     * 判断集合是否为空
     */
    public static boolean isNull(Collection<?> list) {

        return null == list || list.size() == 0;
    }

    /**
     * 判断集合是否为空
     */
    public static boolean isNull(Set<?> set) {

        return null == set || set.size() == 0;
    }

    /**
     * 判断集合是否为空
     */
    public static boolean isNull(Map<?, ?> map) {
        return null == map || map.size() == 0;
    }

    /**
     * 判断Long是否为空
     */
    public static boolean isNull(Long lg) {
        return null == lg || lg == 0;
    }

    /**
     * 判断Integer是否为空
     */
    public static boolean isNull(Integer it) {
        return null == it || it == 0;
    }

    public static boolean isNull(File file) {
        return null == file || !file.exists();
    }

    public static boolean isNull(BigDecimal decimal) {
        return null == decimal || decimal.compareTo(BigDecimal.ZERO) == 0;
    }

    /**
     * 判断数组是否为空
     */
    public static boolean isNull(Object[] strs) {
        return null == strs || strs.length == 0;
    }

    /**
     * 获取数字 空返回0
     */
    public static Number getNumber(Number number) {

        return isNull(number) ? 0L : number;
    }

    /**
     * 数字格式化
     *
     * @param number
     * @param pattern (转化格式，默认#.##，其它的自己上网查)
     * @return
     */
    public static String numberFormat(Number number, String... pattern) {
        if (isNull(pattern)) {
            return FORMAT.format(number);
        }

        return FORMAT.format(pattern[0]);
    }

    private static Format FORMAT = new DecimalFormat("#.##");

    /**
     * 克隆
     *
     * @param o
     * @return
     */
    public static Object clone(Object o) {
        if (null == o) {
            return null;
        }

        // 将对象序列化后写在流里,因为写在流里面的对象是一份拷贝,
        // 原对象仍然在JVM里
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(o);
            ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
            return ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != bos) {
                    bos.close();
                }
                if (null != oos) {
                    oos.close();
                }
                if (null != ois) {
                    ois.close();

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    /**
     * 判断字符串是否非空
     *
     * @param str
     * @return
     */
    public static boolean isNotNull(String str) {
        return !isNull(str);
    }

    /**
     * 判断对象是否非空
     *
     * @param o
     * @return
     */
    public static boolean isNotNull(Object o) {
        return !isNull(o);
    }

    /**
     * 判断集合是否非空
     *
     * @param list
     * @return
     */
    public static boolean isNotNull(List<?> list) {

        return !isNull(list);
    }

    /**
     * 判断集合是否非空
     *
     * @param set
     * @return
     */
    public static boolean isNotNull(Set<?> set) {

        return !isNull(set);
    }

    /**
     * 判断集合是否非空
     *
     * @param map
     * @return
     */
    public static boolean isNotNull(Map<?, ?> map) {
        return !isNull(map);
    }

    /**
     * 判断Long是否非空
     *
     * @param lg
     * @return
     */
    public static boolean isNotNull(Long lg) {
        return !isNull(lg);
    }

    /**
     * 判断Integer是否非空
     *
     * @param it
     * @return
     */
    public static boolean isNotNull(Integer it) {
        return !isNull(it);
    }

    public static boolean isNotNull(File file) {
        return !isNull(file);
    }

    /**
     * 判断数组是否非空
     *
     * @param strs
     * @return
     */
    public static boolean isNotNull(Object[] strs) {
        return !isNull(strs);
    }

    public static boolean isNotNull(BigDecimal decimal) {
        return !isNull(decimal);
    }

    /**
     * obj转String/int/long
     *
     * @param obj
     * @return
     */
    public static String toString(Object obj) {
        return isNull(obj) ? "" : obj.toString();
    }

    public static String toStringNull(Object obj) {
        return isNull(obj) ? null : ("".equals(obj.toString()) ? null : obj.toString());
    }

    public static Integer toInteger(Object obj) {
        return isNull(obj) ? 0 : (isNull(obj.toString()) ? 0 : Integer.parseInt(obj.toString()));
    }

    public static Integer toIntegerNull(Object obj) {
        return isNull(obj) ? null : (isNull(obj.toString()) ? null : Integer.parseInt(obj.toString()));
    }

    public static Long toLong(Object obj) {
        return isNull(obj) ? 0L : (isNull(obj.toString()) ? 0L : Long.parseLong(obj.toString()));
    }

    public static Long toLongNull(Object obj) {
        return isNull(obj) ? null : (isNull(obj.toString()) ? null : Long.parseLong(obj.toString()));
    }

    public static Float toFloat(Object obj) {
        return isNull(obj) ? 0 : (isNull(obj.toString()) ? 0 : Float.parseFloat(obj.toString()));
    }

    public static Double toDouble(Object obj) {
        return isNull(obj) ? 0 : (isNull(obj.toString()) ? 0 : Double.parseDouble(obj.toString()));
    }

    public static Float toFloatNull(Object obj) {
        return isNull(obj) ? null : (isNull(obj.toString()) ? null : Float.parseFloat(obj.toString()));
    }

    public static Boolean toBoolean(Object obj) {
        return !isNull(obj) && (!isNull(obj.toString()) && Boolean.parseBoolean(obj.toString()));
    }

    public static boolean isBlank(String str) {
        return !(str != null && !(str.trim().equals("")));
    }

    public static BigDecimal toBigDecimal(Object value) {
        BigDecimal ret = null;
        if (value != null) {
            if (value instanceof BigDecimal) {
                ret = (BigDecimal) value;
            } else if (value instanceof String) {
                ret = new BigDecimal((String) value);
            } else if (value instanceof BigInteger) {
                ret = new BigDecimal((BigInteger) value);
            } else if (value instanceof Number) {
                ret = new BigDecimal(((Number) value).doubleValue());
            } else {
                throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " into a BigDecimal.");
            }
        }
        return ret;
    }

    /**
     * 判断字符串参数是否为空
     *
     * @param param 参数
     * @return 是否合法
     * @Author zzf
     * @Date 2019/1/5 0005 16:02
     */
    public static boolean checkParam(String param) {
        return param != null && !param.trim().equals("") && !param.trim().toLowerCase().equals("null");
    }

    /**
     * 判断字符串参数是否为空
     *
     * @param param 参数
     * @return 是否合法
     * @Author zzf
     * @Date 2019/1/5 0005 16:02
     */
    public static boolean checkParam(Object param) {
        return param != null && !param.toString().trim().equals("") && !param.toString().trim().toLowerCase().equals("null");
    }


    /**
     * 判断多个字符串参数是否为空
     *
     * @param params 参数集合
     * @return 是否合法
     * @Author zzf
     * @Date 2019/1/5 0005 16:03
     */
    public static boolean checkParams(String... params) {
        for (String param : params) {
            if (!checkParam(param)) {
                return false;
            }
        }
        return true;
    }


    public static boolean checkMapValueIsNotNull(Object val) {
        return val != null && !val.toString().trim().equals("");
    }


    //首字母转小写
    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0))) {
            return s;
        } else {
            return Character.toLowerCase(s.charAt(0)) + s.substring(1);
        }
    }


    //首字母转大写
    public static String toUpperCaseFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0))) {
            return s;
        } else {
            return Character.toUpperCase(s.charAt(0)) + s.substring(1);
        }
    }

    /***
     * 下划线命名转为驼峰命名
     *
     * @param para
     *        下划线命名的字符串
     */
    public static String UnderlineToHump(String para) {
        StringBuilder result = new StringBuilder();
        String[] a = para.split("_");
        for (String s : a) {
            if (!para.contains("_")) {
                result.append(s);
                continue;
            }
            if (result.length() == 0) {
                result.append(s.toLowerCase());
            } else {
                result.append(s.substring(0, 1).toUpperCase());
                result.append(s.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }

    /***
     * 驼峰命名转为下划线命名
     *
     * @param para
     *        驼峰命名的字符串
     */
    public static String HumpToUnderline(String para) {
        StringBuilder sb = new StringBuilder(para);
        int temp = 0;//定位
        if (!para.contains("_")) {
            for (int i = 0; i < para.length(); i++) {
                if (Character.isUpperCase(para.charAt(i))) {
                    sb.insert(i + temp, "_");
                    temp += 1;
                }
            }
        }
        return sb.toString().toLowerCase();
    }


    public static List<Map<String, Object>> getNotNullList(List<Map<String, Object>> list) {
        if (isNull(list)) {
            list = new ArrayList<>();
        }
        return list;
    }


    /**
     * HmacSHA1加密
     *
     * @param data 需要加密的数据
     * @param key  秘钥
     * @Author zzf
     * @Date 2019/3/14 001416:14
     */
    //原文是：123456，加密的密钥为：12345678，最后得到的加密结果是：8fcfc2d7e51f5b502ad1b2270e885e29a7bb81df
    public static String hamcsha1(byte[] data, byte[] key) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            return byte2hex(mac.doFinal(data));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //二行制转字符串
    private static String byte2hex(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b != null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1) {
                hs.append('0');
            }
            hs.append(stmp);
        }
        return hs.toString().toUpperCase();
    }

    /**
     * int类型数据转字符串自动补全前缀0得到自定义位数
     *
     * @param num 需要补全0的数据，默认补全为三位
     * @return
     */
    public static String addZeroForNum(int num) {
        return addZeroForNum(num, 3);
    }

    /**
     * int类型数据转字符串自动补全前缀0得到自定义位数
     *
     * @param num       需要补全0的数据
     * @param strLength 补全0后的字符串长度
     * @return
     */
    public static String addZeroForNum(int num, int strLength) {
        return String.format("%0" + strLength + "d", num);
    }

//
//    /**
//     * 将object对象转成对象集合
//     *
//     * @param obj   需要转换的对象
//     * @param clazz 集合泛型类
//     * @Author zzf
//     * @Date 2019/4/12 001217:16
//     */
//    public static <T> List<T> toBeanList(Object obj, Class<T> clazz) {
//        String str = FastJsonUtil.toJSONString(obj);
//        List<T> list = null;
//        try {
//            list = FastJsonUtil.toList(str, clazz);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return list == null ? new ArrayList<>() : list;
//    }
//
//
//    /**
//     * 将object对象转成指定对象
//     *
//     * @param obj   需要转换的对象
//     * @param clazz 指定对象类
//     * @Author zzf
//     * @Date 2019/4/12 001217:18
//     */
//    public static <T> T toBean(Object obj, Class<T> clazz) {
//        String str = FastJsonUtil.toJSONString(obj);
//        return FastJsonUtil.toBean(str, clazz);
//    }
//
//
//    public static String joinSetVal(Set<String> set) {
//        List<String> list = new ArrayList<>(set);
//        StringBuilder stringBuilder = new StringBuilder();
//        for (int i = 0; i < list.size(); i++) {
//            if (i < list.size() - 1) {
//                stringBuilder.append(list.get(i)).append(Constants.DEFAULT_SPLIT_CHAR);
//            } else {
//                stringBuilder.append(list.get(i));
//            }
//        }
//        return stringBuilder.toString();
//    }
//
//    public static String joinListVal(List<String> list) {
//        StringBuilder stringBuilder = new StringBuilder();
//        for (int i = 0; i < list.size(); i++) {
//            if (i < list.size() - 1) {
//                stringBuilder.append(list.get(i)).append(Constants.DEFAULT_SPLIT_CHAR);
//            } else {
//                stringBuilder.append(list.get(i));
//            }
//        }
//        return stringBuilder.toString();
//    }
//
//    /**
//     * 提取html中的图片src
//     *
//     * @param content
//     * @return
//     */
//    public static String[] getHTMLImgs(String content) {
//        String img = "";
//        Pattern p_image;
//        Matcher m_image;
//        String str = "";
//        String[] images = null;
//        String regEx_img = "(<img.*src\\s*=\\s*(.*?)[^>]*?>)";
//        p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
//        m_image = p_image.matcher(content);
//        while (m_image.find()) {
//            img = m_image.group();
//            Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)")
//                    .matcher(img);
//            while (m.find()) {
//                String tempSelected = m.group(1);
//                if ("".equals(str)) {
//                    str = tempSelected;
//                } else {
//                    String temp = tempSelected;
//                    str = str + "," + temp;
//                }
//            }
//        }
//        if (!"".equals(str)) {
//            images = str.split(",");
//        }
//        return images;
//    }
//    /**
//     * 身份证脱敏
//     * @param cardNo
//     * @return
//     */
//    public static String hideIdCard(String cardNo) {
//        if (StringUtils.isBlank(cardNo)) {
//            return "";
//        }
//        return StringUtils.left(cardNo, 4).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNo, 4), StringUtils.length(cardNo), "*"), "***"));
//    }
//    /**电话脱敏
//     *
//     * @param phone
//     * @return
//     */
//    public static String hidePhone(String phone) {
//        if (StringUtils.isBlank(phone)) {
//            return "";
//        }
//        return StringUtils.left(phone, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(phone, 4), StringUtils.length(phone), "*"), "***"));
//    }
//    /**
//     * 银行卡号脱敏
//     * @param cardNo
//     * @return
//     */
//    public static String hideBankCard(String cardNo) {
//        if (StringUtils.isBlank(cardNo)) {
//            return "";
//        }
//        return StringUtils.left(cardNo, 4).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNo, 4), StringUtils.length(cardNo), "*"), "******"));
//    }
}
